package 设计模式.解释器模式;

import java.util.Stack;

/**
 * @ClassName Calculator
 * @Description 计算器
 *
 * 解释器模式【Interpretor Pattern】给定一个语言，定义它的文法的一种表示，并定义解释器。这个解释器使用该表示来解释语言中的句子。
 *为了解释一种语言，而为语言创建的解释器。
 *解释器模式在生活场景中应用
 * 1.音乐简谱
 * 2.摩斯密码
 *
 *解释器模式的适用场景
 * 1.一些重复出现的问题可以一种简单的语言来进行表达
 * 2.一个简单的语法 需要解释的场景
 *
 */
public class CalculatorModel {
    private Stack<IArithmeticInterpreter> stack = new Stack<>();

    public CalculatorModel(String expression) {
        parse(expression);
    }

    private void parse(String expression) {
        //解析 10 + 20 表达式
        String[] eles = expression.split(" ");
        IArithmeticInterpreter left, right;
        for (int i = 0; i < eles.length; i++) {
            String operator = eles[i];
            if (OperateUtil.ifOperator(operator)) {
                left = this.stack.pop();
                right = new NumInterpreter(Integer.valueOf(eles[++i]));
                System.out.println("出栈：" + left.interpret() + "和" + right.interpret());
                this.stack.push(OperateUtil.getInterpreter(left, right, operator));
                System.out.println("应用运算符：" + operator);
            } else {
                NumInterpreter numInterpreter = new NumInterpreter(Integer.valueOf(eles[i]));
                this.stack.push(numInterpreter);
                System.out.println("入栈：" + numInterpreter.interpret());
            }
        }

    }

    public int calculate() {
        return this.stack.pop().interpret();
    }

    public static void main(String[] args) {
        System.out.println("result:" + new CalculatorModel("10 + 30").calculate());
        System.out.println("---------------------------");
        System.out.println("result:" + new CalculatorModel("10 * 30").calculate());
        System.out.println("---------------------------");
        System.out.println("result:" + new CalculatorModel("10 - 30 + 11").calculate());
        System.out.println("---------------------------");
        System.out.println("result:" + new CalculatorModel("10 / 30 + 10 * 4 - 15").calculate());
    }
}
